package dao_framework;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class dbConn {

	private static final ThreadLocal<Connection> context = new ThreadLocal<Connection>();
	
	public Connection getConnection() throws SQLException {
		Connection conn = null;
		
		String host = "jdbc:mysql://localhost/gesobraauto";
		String username = "app2";
		String pass = "app";
		
			try {
				Class.forName("com.mysql.jdbc.Driver");
				conn = DriverManager.getConnection(host,username,pass);
			} catch (ClassNotFoundException e) {
				throw new ConnectionException("Erro ao aceder à BD.",e); 
			}
			
		return conn;
	}
	
	public void beginTransaction() throws SQLException {
		Connection conn = getConnection();
		conn.setAutoCommit(false);
		context.set(conn);
	}
	
	public void endTransaction() throws SQLException {
		commit(getConnectionFromContext());
		releaseTransaction();
	}
	
	public void releaseTransaction() throws SQLException {
		Connection conn = getConnectionFromContext();
		close(conn);
		context.remove();
	}
	
	public void rollbackTransaction() {
		Connection conn;
		
		try {
			conn = getConnectionFromContext();
			rollback(conn);
			close(conn);
		} catch (SQLException e) {
			throw new ConnectionException("Erro ao efectuar o rollback.",e);
		}
		
		context.remove();
	}
	
	public Connection getConnectionFromContext () throws SQLException {
		Connection conn = context.get();
		
		if (conn == null) throw new SQLException("Transação inválida.");
		
		if (conn.isClosed()) throw new SQLException("Transação inválida. A ligação à BD está fechada.");
		
		return conn;
	}
	
	public void commit(Connection conn) throws SQLException {
		conn.commit(); 
	}
	
	public void rollback(Connection conn) throws SQLException {
		if (conn != null) conn.rollback();
	}
	
	public void close(Statement stmt) {
		if (stmt == null) return;
		
		try {
			stmt.close();
		} catch (SQLException e) {
			throw new ConnectionException("Erro ao fechar o statement.",e);
		}
	}
	
	public void close(Connection conn) {
		if (conn == null) return;
		
		try {
			conn.close();
		} catch (SQLException e) {
			throw new ConnectionException("Erro ao fechar a ligação na BD.",e);
		}
	}
	
	public void close(ResultSet rs) {
		if (rs == null) return;
		
		try {
			rs.close();
		} catch (SQLException e) {
			throw new ConnectionException("Erro ao fechar o resultset.",e);
		}
	}
	
	public void closeAll(Statement stmt, Connection conn) {
		close(stmt);
		close(conn);
	}

	public void closeAll(Statement stmt, Connection conn, ResultSet rs) {
		closeAll(stmt, conn);
		close(rs);
	}


}
